﻿#region references
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System;

/* Project dependencies */
using IcaGames.Objects;
using IcaGames.Logging;
#endregion

namespace IcaGames.Database.ObjectManagement
{
    /*
     * Class that handles the functions for adding and deleting games from the shopping cart.
     * 
     * @author
     * Rick Oonk
     * 
     * @version
     * 1.0
     * 
     * @update
     * 20-01-2010 by Rick Oonk.
     * Created Class and added attributes and standard functions. 
     */
    public static class CartManagement
    {
        /*
         * Function to add an existing Game to the shopping cart again.
         * 
         * @param
         * cart: The list with Games that are in the shopping cart.
         * gameNr: The gameNr of the Game that has to be added.
         * pf: The Platform of the selected Game.
         * 
         * @returns
         * The list with Games that are in the shopping cart.
         */
        public static List<Game> AddGameAmount(List<Game> cart, int gameNr, Platform pf)
        {
            foreach (Game g in cart)
            {
                if (g.GameNr == gameNr && g.Platform == pf)
                {
                    g.Amount++;

                    break;
                }
            }
            return cart;
        }

        /*
         * Function to add a Game to the Shopping cart of the user.
         * 
         * @param
         * cartId: The cartId of the current shopping cart.
         * cart: The list with Games that are in the shopping cart.
         * g: The game that has to be added.
         * pf: The Platform of the selected Game.
         * 
         * @returns
         * The list with games that are in the shopping cart.
         */
        public static List<Game> AddGameToCart(int cartId, List<Game> cart, Game g)
        {
            bool exists = false;
            foreach (Game game in cart)
            {
                if (game.GameNr == g.GameNr && game.Platform == g.Platform)
                {
                    game.Amount++; g.Amount = game.Amount;
                    if (cartId > 0) { UpdateShoppingCartGame(cartId, g); }
                    exists = true;
                }
            }
            if (!exists)
            {
                g.Amount++;
                cart.Add(g);
                if (cartId > 0) { SaveShoppingCartGame(cartId, g); }
                exists = false;
            }

            return cart;
        }

        /*
         * Function to delete a Game from the Shopping cart of the user.
         * 
         * @param
         * cartId: The cartId of the current shopping cart. The id is 0 if the shopping cart is not yet saved.
         * cart: The list with Games that are in the shopping cart.
         * gameNr: The gameNr of the Game that has to be deleted.
         * pf: The Platform of the selected Game.
         * 
         * @returns
         * The list with games that are in the shopping cart.
         */
        public static List<Game> DeleteGameFromCart(int cartId, List<Game> cart, int gameNr, Platform pf)
        {
            foreach (Game g in cart)
            {
                if (g.GameNr == gameNr && g.Platform == pf)
                {
                    if (g.Amount > 1)
                    {
                        g.Amount--;
                        if (cartId > 0) { UpdateShoppingCartGame(cartId, g); }
                        break;
                    }
                    else if (g.Amount == 1)
                    {
                        cart.Remove(g);
                        if (cartId > 0) { DeleteShoppingCartGame(cartId, g); }
                        break;
                    }
                }
            }

            return cart;
        }

        /*
         * Function to save the shopping cart into the database.
         * 
         * @param
         * userId: The userId of the user that is currently logged in and has made a shopping cart.
         * cart: The shopping cart of the user.
         * 
         * @returns
         * True if the shopping cart was succesfully saved into the database.
         * False if the shopping cart was not succesfully saved into the database.
         */
        public static int SaveShoppingCart(int userId, List<Game> cart)
        {
            SqlCommand command = null;
            SqlTransaction trans = null;
            string commandText = "spSaveShoppingCart";
            int cartId = -1;

            try
            {
                command = Connection.GetCommand(commandText);
                command.CommandType = CommandType.StoredProcedure;

                /* Create transaction to rollback if something went wrong */
                trans = command.Connection.BeginTransaction();
                command.Transaction = trans;

                command.Parameters.AddWithValue("@userId", userId);
                command.Parameters.AddWithValue("@date", DateTime.Now);
                command.Parameters.AddWithValue("@paid", "Nee");
                command.Parameters.AddWithValue("@creditcard", 1);
                command.Parameters.AddWithValue("@ip", "192.168.1.1");

                cartId = Convert.ToInt32(command.ExecuteScalar());
                command.Parameters.Clear();
                command.CommandText = "spSaveShoppingCartGame";

                foreach (Game g in cart)
                {
                    command.Parameters.AddWithValue("@cartId", cartId);
                    command.Parameters.AddWithValue("@gameNr", g.GameNr);
                    command.Parameters.AddWithValue("@platformId", g.Platform);
                    command.Parameters.AddWithValue("@dateGame", DateTime.Now.AddDays(7));
                    command.Parameters.AddWithValue("@dateImage", DateTime.Now.AddDays(7));
                    command.Parameters.AddWithValue("@amount", g.Amount);
                    command.Parameters.AddWithValue("@downloads", g.Amount);

                    command.ExecuteNonQuery();
                    command.Parameters.Clear();
                }

                trans.Commit();
            }
            catch (Exception ex)
            {
                Log.CreateLog("Exception while inserting shopping cart", "CARTMANAGEMENT");
                Log.CreateLog(ex.Message, "CARTMANAGEMENT");
                trans.Rollback();

                return -1;
            }
            finally
            {
                Connection.CloseCommand(command);
            }

            return cartId;
        }

        /*
         * Function to check if a authenticated user allready has a saved shopping cart.
         * 
         * @param
         * userId: The userId of the authenticated user.
         * paid: If the cart has been paid or not.
         * 
         * @returns
         * True if the user allready has a saved shopping cart.
         * False if the user does not have a saved shopping cart.
         */
        public static ShoppingCart GetShoppingCart(int userId, string paid)
        {
            SqlCommand command = null;
            SqlDataReader dr = null;
            string commandText = "spCheckSavedShoppingCart";
            ShoppingCart c = new ShoppingCart();

            try
            {
                command = Connection.GetCommand(commandText);
                command.CommandType = CommandType.StoredProcedure;
                command.Parameters.AddWithValue("@userId", userId);
                command.Parameters.AddWithValue("@paid", paid);

                dr = Connection.GetSqlDataReader(command);
                while (dr.Read())
                {
                    c.CartId = Cast.CastToInteger(dr["WINKELWAGEN_ID"]);
                    c.Date = Cast.CastToDateTime(dr["DATUM"]);
                    c.UserId = Cast.CastToInteger(dr["KLANT_ID"]);
                }
            }
            catch (Exception ex)
            {
                Log.CreateLog("Exception while checking shopping cart", "CARTMANAGEMENT");
                Log.CreateLog(ex.Message, "CARTMANAGEMENT");
            }
            finally
            {
                Connection.CloseCommand(command, dr);
            }

            return c;
        }

        /*
         * Function to check if a authenticated user allready has a saved shopping cart.
         * 
         * @param
         * userId: The userId of the authenticated user.
         * paid: If the cart has been paid or not.
         * 
         * @returns
         * True if the user allready has a saved shopping cart.
         * False if the user does not have a saved shopping cart.
         */
        public static List<ShoppingCart> GetShoppingCarts(int userId, string paid)
        {
            SqlCommand command = null;
            SqlDataReader dr = null;
            string commandText = "spCheckSavedShoppingCart";
            List<ShoppingCart> cartList = new List<ShoppingCart>();

            try
            {
                command = Connection.GetCommand(commandText);
                command.CommandType = CommandType.StoredProcedure;
                command.Parameters.AddWithValue("@userId", userId);
                command.Parameters.AddWithValue("@paid", paid);

                dr = Connection.GetSqlDataReader(command);
                while (dr.Read())
                {
                    ShoppingCart c = new ShoppingCart
                    {
                        CartId = Cast.CastToInteger(dr["WINKELWAGEN_ID"]),
                        Date = Cast.CastToDateTime(dr["DATUM"]),
                        UserId = Cast.CastToInteger(dr["KLANT_ID"])
                    };
                    cartList.Add(c);
                }
            }
            catch (Exception ex)
            {
                Log.CreateLog("Exception while checking shopping cart", "CARTMANAGEMENT");
                Log.CreateLog(ex.Message, "CARTMANAGEMENT");
            }
            finally
            {
                Connection.CloseCommand(command, dr);
            }

            return cartList;
        }

        /*
         * Function to get the games for an existing shopping cart from the database.
         * 
         * @param
         * cartId: The cartId of the specified shopping cart.
         * 
         * @returns
         * The games from the shopping cart.
         */
        public static List<Game> GetShoppingCartGames(int cartId)
        {
            SqlCommand command = null;
            SqlDataReader dr = null;
            string commandText = "spGetShoppingCartGames";
            List<Game> cart = new List<Game>();

            try
            {
                command = Connection.GetCommand(commandText);
                command.CommandType = CommandType.StoredProcedure;
                command.Parameters.AddWithValue("@cartId", cartId);

                dr = Connection.GetSqlDataReader(command);
                while (dr.Read())
                {
                    Game g = new Game
                    {
                        DescriptionLong = Cast.CastToString(dr["BESCHRIJVING_UITGEBREID"]),
                        DescriptionShort = Cast.CastToString(dr["BESCHRIJVING_KORT"]),
                        GameNr = Cast.CastToInteger(dr["GAME_NR"]),
                        GameSize = Cast.CastToInteger(dr["GROOTTE"]),
                        Platform = (Platform)Cast.CastToInteger(dr["PLATFORM_ID"]),
                        Price = Cast.CastToDecimal(dr["PRIJS"]),
                        Publisher = new Publisher(
                            Cast.CastToInteger(dr["MAKER_ID"]),
                            Cast.CastToString(dr["NAAM"])),
                        Sold = Cast.CastToInteger(dr["VERKOCHT"]),
                        Stock = Cast.CastToInteger(dr["VOORRAAD"]),
                        Title = Cast.CastToString(dr["TITEL"]),
                        Amount = Cast.CastToInteger(dr["AANTAL"]),
                        Downloads = Cast.CastToInteger(dr["DOWNLOADS"]),
                        DownloadLimit = Cast.CastToDateTime(dr["DATETIMEDOWNLOADGAME"])
                    };
                    cart.Add(g);
                }
            }
            catch (Exception ex)
            {
                Log.CreateLog("Exception while getting shopping cart games", "CARTMANAGEMENT");
                Log.CreateLog(ex.Message, "CARTMANAGEMENT");
            }
            finally
            {
                Connection.CloseCommand(command, dr);
            }

            return cart;
        }

        /*
         * Function to insert a new game into a existing shopping cart.
         * 
         * @param
         * cartId: The id of the current shopping cart.
         * g: The Game that has to be saved.
         * 
         * @returns
         * True if the update was succesfull.
         * False if the update was not succesfull.
         */
        public static bool SaveShoppingCartGame(int cartId, Game g)
        {
            SqlCommand command = null;
            string commandText = "spSaveShoppingCartGame";

            try
            {
                command = Connection.GetCommand(commandText);
                command.CommandType = CommandType.StoredProcedure;

                command.Parameters.AddWithValue("@cartId", cartId);
                command.Parameters.AddWithValue("@gameNr", g.GameNr);
                command.Parameters.AddWithValue("@platformId", g.Platform);
                command.Parameters.AddWithValue("@dateGame", DateTime.Now);
                command.Parameters.AddWithValue("@dateImage", DateTime.Now);
                command.Parameters.AddWithValue("@amount", g.Amount);
                command.Parameters.AddWithValue("@downloads", g.Amount);

                command.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                Log.CreateLog("Exception while inserting shopping cart game", "CARTMANAGEMENT");
                Log.CreateLog(ex.Message, "CARTMANAGEMENT");
                return false;
            }
            finally
            {
                Connection.CloseCommand(command);
            }

            return true;
        }

        /*
         * Function to update an existing shopping cart.
         * 
         * @param
         * cartId: The id of the current shopping cart.
         * paid: If the order has been paid.
         * 
         * @returns
         * True if the update was succesfull.
         * False if the update was not succesfull.
         */
        public static bool UpdateShoppingCart(int cartId, string paid)
        {
            SqlCommand command = null;
            string commandText = "spUpdateShoppingCart";

            try
            {
                command = Connection.GetCommand(commandText);
                command.CommandType = CommandType.StoredProcedure;
                command.Parameters.AddWithValue("@cartId", cartId);
                command.Parameters.AddWithValue("@paid", paid);

                command.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                Log.CreateLog("Exception while updating shopping cart", "CARTMANAGEMENT");
                Log.CreateLog(ex.Message, "CARTMANAGEMENT");
                return false;
            }
            finally
            {
                Connection.CloseCommand(command);
            }
            return true;
        }

        /*
         * Function to update a saved shopping cart with new information.
         * 
         * @param
         * cartId: The id of the current shopping cart.
         * g: The Game that has to be updated.
         * 
         * @returns
         * True if the update was succesfull.
         * False if the update was not succesfull.
         */
        public static bool UpdateShoppingCartGame(int cartId, Game g)
        {
            SqlCommand command = null;
            SqlTransaction trans = null;
            string commandText = "spUpdateShoppingCartGame";

            try
            {
                command = Connection.GetCommand(commandText);
                command.CommandType = CommandType.StoredProcedure;

                /* Create transaction to rollback if something went wrong */
                trans = command.Connection.BeginTransaction();
                command.Transaction = trans;

                command.Parameters.AddWithValue("@cartId", cartId);
                command.Parameters.AddWithValue("@gameNr", g.GameNr);
                command.Parameters.AddWithValue("@platformId", g.Platform);
                command.Parameters.AddWithValue("@amount", g.Amount);

                command.ExecuteNonQuery();
                trans.Commit();
            }
            catch (Exception ex)
            {
                Log.CreateLog("Exception while updating shopping cart games", "CARTMANAGEMENT");
                Log.CreateLog(ex.Message, "CARTMANAGEMENT");
                trans.Rollback();
                return false;
            }
            finally
            {
                Connection.CloseCommand(command);
            }

            return true;
        }

        /*
         * Function to delete a game from a saved shopping cart.
         * 
         * @param
         * cartId: The id of the current shopping cart.
         * g: The Game that has to be deleted.
         */
        public static bool DeleteShoppingCartGame(int cartId, Game g)
        {
            SqlCommand command = null;
            SqlTransaction trans = null;
            string commandText = "spDeleteShoppingCartGame";

            try
            {
                command = Connection.GetCommand(commandText);
                command.CommandType = CommandType.StoredProcedure;

                /* Create transaction to rollback if something went wrong */
                trans = command.Connection.BeginTransaction();
                command.Transaction = trans;

                command.Parameters.AddWithValue("@cartId", cartId);
                command.Parameters.AddWithValue("@gameNr", g.GameNr);
                command.Parameters.AddWithValue("@platformId", g.Platform);

                command.ExecuteNonQuery();
                trans.Commit();
            }
            catch (Exception ex)
            {
                Log.CreateLog("Exception while deleting shopping cart games", "CARTMANAGEMENT");
                Log.CreateLog(ex.Message, "CARTMANAGEMENT");
                trans.Rollback();
                return false;
            }
            finally
            {
                Connection.CloseCommand(command);
            }
            return true;
        }

        /*
         * Function to refresh the shoppint cart contents on the MasterPage.
         * 
         * @param
         * cart: The list with games that are in the shopping cart.
         * 
         * @returns
         * A decimal array containing the refreshed cart information.
         */
        public static decimal[] RefreshShoppingCart(List<Game> cart)
        {
            decimal[] cartContents = new decimal[2];

            decimal totalPrice = 0, totalAmount = 0;
            foreach (Game g in cart)
            {
                decimal subPrice = g.Price * g.Amount;
                totalPrice += subPrice;
                totalAmount += g.Amount;
            }
            cartContents[0] = totalPrice;
            cartContents[1] = totalAmount;

            return cartContents;
        }

        /*
         * Function to update the downloads for the specified game, cart and user.
         * 
         * @param
         * cartId: The id of the shopping cart of the game.
         * gameNr: The id of the game that has been downloaded.
         * platform: The platform for which the download has been completed.
         * 
         * @returns
         * True if the update was succesfull.
         * False if the update was not succesfull.
         */
        public static bool UpdateUserDownloads(int cartId, int gameNr, string platform)
        {
            SqlCommand command = null;
            string commandText = "spUpdateUserDownloads";

            try
            {
                int platformId = PlatformValue.GetPlatformValue(platform);

                command = Connection.GetCommand(commandText);
                command.CommandType = CommandType.StoredProcedure;
                command.Parameters.AddWithValue("@cartId", cartId);
                command.Parameters.AddWithValue("@gameNr", gameNr);
                command.Parameters.AddWithValue("@platform", platformId);

                command.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                Log.CreateLog("Exception while updating user downloads", "CARTMANAGEMENT");
                Log.CreateLog(ex.Message, "CARTMANAGEMENT");
                return false;
            }
            finally
            {
                Connection.CloseCommand(command);
            }

            return true;
        }

        /*
         * Function to check if the user has downloads available for the selected game.
         * 
         * @param
         * cartId: The id of the shopping cart of the game.
         * gameNr: The id of the game that has been downloaded.
         * platform: The platform for which the download has been completed.
         * 
         * @returns
         * True if the user has downloads available.
         * False if the user doesn't have downloads available.
         */
        public static bool CheckDownloadAvailable(int cartId, int gameNr, string platform)
        {
            SqlCommand command = null;
            string commandText = "spCheckDownloadsAvailable";
            bool value = false;

            try
            {
                int platformId = PlatformValue.GetPlatformValue(platform);

                command = Connection.GetCommand(commandText);
                command.CommandType = CommandType.StoredProcedure;
                command.Parameters.AddWithValue("@cartId", cartId);
                command.Parameters.AddWithValue("@gameNr", gameNr);
                command.Parameters.AddWithValue("@platform", platformId);

                int rows = Convert.ToInt32(command.ExecuteScalar());
                if (rows > 0) { value = true; }
            }
            catch (Exception ex)
            {
                Log.CreateLog("Exception while checking user downloads", "CARTMANAGEMENT");
                Log.CreateLog(ex.Message, "CARTMANAGEMENT");
                value = false;
            }
            finally
            {
                Connection.CloseCommand(command);
            }

            return value;
        }
    }
}
